<template>
  <div class="connectTemp">
    <el-form
      :model="formData"
      ref="appFrom"
      label-width="120px"
      size="small"
      :rules="rules"
      :disabled="disabled"
    >
      <el-collapse v-model="activeName">
        <el-collapse-item title="基本信息" :name="0">
          <el-row>
            <el-col :span="12">
              <el-form-item label="链接名称" prop="name">
                <el-input v-model="formData.name"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="编码" prop="code">
                <el-input disabled v-model="formData.code"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="20">
              <el-form-item label="描述" prop="description">
                <el-input v-model="formData.description"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="类型" prop="type">
                <el-select v-model="formData.type" @change="changeDataType">
                  <el-option
                    v-for="item in typeListBasic"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="启用" prop="enable">
                <el-switch
                  :active-value="1"
                  :inactive-value="0"
                  v-model="formData.enable"
                >
                </el-switch>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="formData.type === 1">
            <el-col :span="12">
              <el-form-item label="方法编码" prop="requestMethod">
                <el-select
                  v-model="formData.requestMethod"
                  @change="(val) => changeMethod(val)"
                >
                  <el-option
                    v-for="item in methodCodeList"
                    :key="item.executorHandler"
                    :label="item.methodDesc"
                    :value="item.executorHandler"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12"> </el-col>
          </el-row>
          <el-row v-if="formData.type === 2">
            <el-col :span="20">
              <el-form-item label="请求URL" prop="requestUrl">
                <el-input v-model="formData.requestUrl"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="formData.type === 2">
            <el-col :span="12">
              <el-form-item label="请求方式" prop="requestType">
                <el-select v-model="formData.requestType">
                  <el-option
                    v-for="item in methodList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12"> </el-col>
          </el-row>
          <el-row v-if="formData.type === 2">
            <el-col :span="20">
              <el-form-item label="成功状态码" prop="successCode">
                <el-input v-model="formData.successCode"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="formData.type === 2">
            <el-col :span="20">
              <el-form-item label="是否JSON格式" prop="whetherJson">
                <el-switch
                  v-model="formData.whetherJson"
                  active-text="是"
                  inactive-text="否"
                  :active-value="1"
                  :inactive-value="0"
                ></el-switch>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="formData.type === 3">
            <el-col :span="12">
              <el-form-item label="实体名称" prop="entityModelName">
                <el-select-tree
                  @change="changeModelName"
                  v-model="formData.entityModelName"
                  :options="entityList"
                ></el-select-tree>
              </el-form-item>
            </el-col>
            <el-col :span="12"> </el-col>
          </el-row>
          <el-row v-if="formData.type === 4">
            <el-col :span="12">
              <el-form-item label="关系名称" prop="entityModelName">
                <el-select-tree
                  v-model="formData.entityModelName"
                  :options="connectList"
                ></el-select-tree>
              </el-form-item>
            </el-col>
            <el-col :span="12"> </el-col>
          </el-row>
          <el-row v-if="formData.type === 3">
            <el-col :span="12">
              <el-form-item label="实体方法">
                <el-select-tree
                  v-model="formData.requestMethod"
                  :options="methodList"
                  @change="(val) => changeEntityMethod(val)"
                  :onLeaf="true"
                  :props="{
                    value: 'name',
                    children: 'children',
                    label: 'apiNameCn',
                  }"
                ></el-select-tree> </el-form-item
            ></el-col>
            <el-col :span="12"> </el-col>
          </el-row>
        </el-collapse-item>
        <el-collapse-item title="API" :name="1">
          <el-row>
            <el-col :span="24">
              <el-form-item label="URL">
                <div class="info">{{ connectInfo.apiUrl }}</div>
              </el-form-item></el-col
            >
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="参数">
                <div class="info">{{ connectInfo.params }}</div>
              </el-form-item></el-col
            >
          </el-row>
        </el-collapse-item>
        <el-collapse-item title="配置" :name="2">
          <div>
            <el-button type="text" @click="addOption">增加配置</el-button>
          </div>
          <div class="header-wrap" v-if="attributeList.length > 0">
            <div class="jsonTips"></div>
            <div class="input-warp">Name</div>
            <div class="input-warp">Operate</div>
            <div class="input-warp">Type</div>
            <div class="input-warp">Value</div>
            <div class="input-warp-small" v-if="formData.type === 3 && formData.requestMethod==='tree'">IsParent</div>
            <div class="input-warp-small" v-else>Required</div>
            <div class="input-warp-small"></div>
          </div>
          <ul class="url-wrap">
            <li
              v-for="(item, idx) in attributeList"
              :key="item.oid"
              class="li-wrap"
            >
              <div class="jsonTips">
                <el-popover
                  placement="top"
                  width="500"
                  trigger="hover"
                  v-if="item.whetherJson"
                >
                  <div class="codeBox">
                    <code-editor
                      :mode="'javascript'"
                      v-model="item.jsonFormat"
                      disabled
                      :formatJson="true"
                      ref="ecEditor"
                    ></code-editor>
                  </div>
                  <el-button slot="reference" class="no-border-btn"
                    >json</el-button
                  >
                </el-popover>
              </div>
              <el-select
                v-model="item.name"
                v-if="formData.type === 3"
                class="input-warp no-border gray"
              >
                <el-option
                  v-for="item in originAttributeList"
                  :key="item.columnName"
                  :label="item.nameCn"
                  :value="item.columnName"
                ></el-option>
              </el-select>

              <el-input
                v-model="item.name"
                v-else
                class="input-warp no-border gray"
              />

              <el-select v-model="item.operate" class="input-warp no-border">
                <el-option
                  v-for="item in operateList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
              <el-select
                v-model="item.type"
                @change="(val) => changeType(val, item)"
                class="input-warp no-border gray"
              >
                <el-option
                  v-for="item in typeList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
              <el-select
                v-model="item.value"
                v-if="item.type === 'expression'"
                class="input-warp"
              >
                <el-option
                  v-for="item in expressionList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
              <el-input v-model="item.value" v-else class="input-warp" />
              <el-switch
                class="input-warp-small"
                v-model="item.required"
                :active-value="1"
                :inactive-value="0"
              >
              </el-switch>
              <el-button
                size="mini"
                type="text"
                @click="deleteOption(item, idx)"
                class="el-icon-delete input-warp-small"
              ></el-button>
            </li>
          </ul>
        </el-collapse-item>
      </el-collapse>
    </el-form>

    <div class="md-component-btns">
      <el-button size="medium" type="primary" @click="save" :disabled="disabled"
        >保存</el-button
      >
      <el-button size="medium" @click="$emit('removeThisTabs')">取消</el-button>
    </div>
  </div>
</template>
<script>
import * as api from "@/api/connect/index";
import ElSelectTree from "@/components/el-select-tree.vue";
import * as entityApi from "@/api/modulManage/entity";
import { generateId } from "@/util/util";
import CodeEditor from "@/components/code-editor/index";

export default {
  name: "connectTemp",
  components: { ElSelectTree, CodeEditor },
  data() {
    return {
      disabled: false,
      activeName: [0, 1, 2, 3],
      formData: {
        enable: 1,
        type: 2,
        whetherJson: 1,
        successCode: "200",
      },
      detailData: {},
      rules: {
        name: [
          {
            required: true,
            message: "请输入连接名称",
            trigger: "blur",
          },
        ],
        code: [
          {
            required: true,
            message: "请输入编码名称",
            trigger: "blur",
          },
        ],
        type: [
          {
            required: true,
            message: "请选择类型",
            trigger: "blur",
          },
        ],
        entityModelName: [
          {
            required: true,
            message: "请选择实体名称",
            trigger: "blur",
          },
        ],

        enable: [
          {
            required: true,
            message: "请选择是否启用",
            trigger: "blur",
          },
        ],
        requestType: [
          {
            required: true,
            message: "请选择请求方式",
            trigger: "blur",
          },
        ],
        requestMethod: [
          {
            required: true,
            message: "请选择实体方法",
            trigger: "blur",
          },
        ],
        requestUrl: [
          {
            required: true,
            message: "请输入请求URL",
            trigger: "blur",
          },
        ],
      },
      connectInfo: {
        url: "",
        params: "",
      },
      typeListBasic: [
        {
          label: "全局方法",
          value: 1,
        },
        {
          label: "HTTP请求",
          value: 2,
        },
        {
          label: "实体方法",
          value: 3,
        },
        {
          label: "关系方法",
          value: 4,
        },
      ],
      entityList: [],
      connectList: [],
      attributeList: [],
      originAttributeList: [],
      typeList: [
        {
          label: "参数",
          value: "param",
        },
        {
          label: "值",
          value: "value",
        },
        {
          label: "表达式",
          value: "expression",
        },
      ],
      expressionList: [
        {
          label: "当前时间",
          value: "currentDate",
        },
        {
          label: "当前用户",
          value: "currentUser",
        },
      ],
      operateList: [
        {
          label: "设置为",
          value: "equal",
        },
        {
          label: "大于",
          value: "greater",
        },
        {
          label: "大于且包含",
          value: "greaterAndEqual",
        },
        {
          label: "小于",
          value: "less",
        },
        {
          label: "小于且包含",
          value: "lessAndEqual",
        },
        {
          label: "包含",
          value: "include",
        },
        {
          label: "模糊匹配",
          value: "like",
        },
      ],
      methodList: [
        {
          label: "POST",
          value: "POST",
        },
        {
          label: "GET",
          value: "GET",
        },
      ],
      methodCodeList: [],
    };
  },
  props: {
    type: String,
    data: Object,
  },
  watch: {
    "formData.type": {
      handler(v, oldV) {
        if (v === oldV) {
          return;
        }
        this.attributeList = [];
        if (v === 4) {
          this.getReferenceList();
        }
        if (v === 3) {
          this.getEntityList();
        }
        if (v === 2) {
          this.methodList = [
            {
              label: "POST",
              value: "POST",
            },
            {
              label: "GET",
              value: "GET",
            },
          ];
        }
        if (v === 1) {
          this.getHandler();
        }
      },
    },

    attributeList: {
      handler(v) {
        if (v.length > 0) {
          const newArr = v
            .filter((v) => v.type === "param" && v.value)
            .map((v) => v.value);
          this.connectInfo.params = newArr.join(",");
        }
      },
      deep: true,
      immediate: true,
    },
  },

  methods: {
    changeDataType() {
      if (this.formData.requestMethod) {
        delete this.formData.requestMethod;
      }
      if (this.formData.entityModelName) {
        delete this.formData.entityModelName;
      }
    },
    changeModelName(val) {
      this.getMethodList(val);
      this.getAttributeList(val);
    },
    changeEntityMethod(val) {
      if (!val || this.formData.type !== 3 || val!=='tree') {
        return;
      }
      const [idAttr] = this.attributeList.filter((v) => v.name === "id_");
      const notIdAttr = this.attributeList.filter((v) => v.name !== "id_");
      if (idAttr) {
        const prdAttr = notIdAttr.slice(0, 1);
        this.attributeList = [{...idAttr,required:false}, ...prdAttr];
      } else {
        this.attributeList = notIdAttr.slice(0, 2);
      }
    },
    changeMethod(val) {
      if (!val) {
        return;
      }
      const [selected] = this.methodCodeList.filter(
        (v) => v.executorHandler === val
      );
      if (!selected || !selected.paramList || selected.paramList.length === 0) {
        return;
      }
      this.attributeList = selected.paramList.map((v) => ({
        oid: generateId(),
        value: v.name,
        name: v.name,
        type: "param",
        operate: "equal",
        required: 0,
        whetherJson: !!v.whetherJson,
        jsonFormat: v.jsonFormat,
      }));
    },
    getDetail() {
      api.detail({ id: this.data.id }).then((res) => {
        if (!res.data.data) {
          return;
        }
        const dataObj = res.data.data;
        this.detailData = res.data.data;
        if (dataObj.type === 3) {
          this.getMethodList(dataObj.entityModelName);
          this.getAttributeList(dataObj.entityModelName, false);
        }
        this.formData = { ...dataObj };
        this.connectInfo = {
          apiUrl: dataObj.apiUrl,
          params: dataObj.parameter,
        };
        this.$nextTick(() => {
          this.attributeList = dataObj.connectorItemList || [];
        });
      });
    },
    addOption() {
      this.attributeList.unshift({
        oid: generateId(),
        value: "",
        name: "",
        type: "param",
        operate: "equal",
        required: 0,
      });
    },

    changeType(val, item) {
      item.value = "";
    },
    deleteOption(option, index) {
      this.attributeList.splice(index, 1);
    },
    save() {
      this.$refs.appFrom.validate((f) => {
        if (f) {
          const {
            name,
            code,
            description,
            type,
            enable,
            entityModelName,
            requestMethod,
            requestUrl,
            whetherJson,
            successCode,
            requestType,
          } = this.formData;
          let paramsData = {
            name,
            code,
            description,
            type,
            enable,
            requestMethod,
            apiUrl: this.connectInfo.apiUrl,
            parameter: this.connectInfo.params,
            connectorItemList: this.attributeList.map((v) => ({
              name: v.name,
              operate: v.operate,
              type: v.type,
              value: v.value,
              required: v.required,
            })),
          };
          if (type === 3 || type === 4) {
            paramsData.entityModelName = entityModelName;
          }
          if (type === 2) {
            paramsData.requestUrl = requestUrl;
            paramsData.whetherJson = whetherJson;
            paramsData.successCode = successCode;
            paramsData.requestType = requestType;
          }
          const method = this.type === "open" ? "insert" : "update";
          if (this.type === "edit") {
            paramsData.id = this.data.id;
          }
          api[method](paramsData).then(() => {
            this.$message.success(
              `${method === "insert" ? "新增" : "编辑"}成功`
            );
            this.$emit("refresh");
            this.$emit("removeThisTabs");
          });
        }
      });
    },
    open() {
      this.disabled = false;
      this.getConnectInfo();
    },
    view() {
      this.disabled = true;
      this.getDetail();
    },
    edit() {
      this.disabled = false;
      this.getDetail();
    },
    getConnectInfo() {
      api.generateApiUrl().then((res) => {
        if (res.data.success) {
          this.connectInfo = res.data.data;
          this.formData = {
            ...this.formData,
            code: this.connectInfo.code,
            name: this.connectInfo.code,
          };
        }
      });
    },
    getEntityList() {
      entityApi.from_to().then((res) => {
        this.entityList = res.data.data || [];
      });
    },
    getReferenceList() {
      api.getReferenceList().then((res) => {
        this.connectList = res.data.data || [];
      });
    },
    async getMethodList(val) {
      const res = await api.getAllOperationTreeByTypeName({ typeName: val });
      this.methodList = res.data.data || [];
    },
    getAttributeList(val, isInit = true) {
      entityApi.getTypeAllAttributeByName({ typeName: val }).then((res) => {
        const newData = res.data.data || [];
        if (isInit) {
          this.attributeList = newData.map((v) => ({
            ...v,
            name: v.columnName,
            type: "param",
            value: v.columnName,
            operate: "equal",
          }));
        }
        this.originAttributeList = [...newData];
      });
    },
    getHandler() {
      api.getHandler().then((res) => {
        if (res.data && res.data.data.length > 0) {
          this.methodCodeList = res.data.data;
        }
      });
    },
  },
  mounted() {},
};
</script>
<style lang="scss" scoped>
.connectTemp {
  width: 100%;
  .header-wrap {
    padding-left: 20px;
    display: flex;
  }
  .info {
    word-break: break-all;
    padding-right: 20px;
  }
  .jsonTips {
    width: 100px;
  }
  .url-wrap {
    list-style: none;
    padding-inline-start: 6px;
    padding-left: 20px; /* 重置IE11默认样式 */

    .li-wrap {
      margin-bottom: 5px;
      display: flex;
      align-items: center;
      position: relative;
      .tips {
        white-space: nowrap;
        margin: 0 10px;
      }

      ::v-deep .no-border .el-input__inner {
        border: none;
      }
      ::v-deep .no-border-btn {
        border: none;
        padding: 5px;
      }
      ::v-deep .gray .el-input__inner {
        background-color: #f5f7fa;
      }
    }
  }
  .input-warp {
    width: 160px;
    padding: 0 10px;
    text-align: center;
  }
  .input-warp-small {
    width: 120px;
    padding: 0 10px;
    text-align: center;
  }
}
.codeBox {
  height: 400px;
  overflow: auto;
}
</style>
